﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace JasRibbonApplicatie.Model
{
    class MateriaalModel:Model
    {
        public MateriaalModel()
        {
            Console.WriteLine("MateriaalModel Created");
        }

        // uit DocumentatieERD: codes materiaal van m0000 tot mzzzz (ongevoelig voor hoofdletters)
        // gelijkaardig voor andere scancodes!
        public const int LENGTH_SCANCODES = 5;

        public List<MateriaalBestelling> GetMateriaalBestellingenByAanvraagId(int aanvraag_id)
        {
            return (from materiaalbestelling in entities.MateriaalBestelling
                    where materiaalbestelling.aanvraag_id.Equals(aanvraag_id)
                    select materiaalbestelling).ToList();
        }

        // GetMateriaalOntleningenByAanvraagId wordt momenteel niet gebruikt???
        public List<Ontlening> GetMateriaalOntleningenByAanvraagId(int aanvraag_id)
        {
            return (from item in entities.Ontlening
                    where item.aanvraag_id.Equals(aanvraag_id)
                    && item.streepjescode.ToLower().First().Equals('m')
                    select item).ToList();
        }
        public bool IsProductNietUitgeleendMomenteel(String scancode)
        {
            int aantalOntleningen = (from entries in entities.Ontlening
                                     where entries.streepjescode.Equals(scancode)
                                     && entries.tijdstip_inlevering.Equals(DateTime.MinValue)
                                     select entries).Count();
            return (aantalOntleningen == 0);
        }

        public List<Materiaaltype> GetAllMateriaalType()
        {
            return (from product in entities.Materiaaltype
                    orderby product.type
                    select product).ToList();
        }

        public Materiaaltype GetMateriaalTypeByMateriaalTypeId(int materiaalType_id)
        {
            var materiaaltypes = from product in entities.Materiaaltype
                                 where product.materiaalType_id.Equals(materiaalType_id)
                                 select product;
            if (materiaaltypes.Count() > 0)
                return materiaaltypes.First();
            return null;
        }

        /*
         * Returns 'null' wanneer de opgegeven code niet voorkomt in de tabel
         */
        public Materiaaltype GetMateriaalTypeByMateriaalScancode(String code)
        {
            var materiaalcodeQuery = from product in entities.Materiaal
                                     where product.streepjescode.ToLower().Equals(code.ToLower())
                                     select product.materiaaltype;
            if (materiaalcodeQuery.Count() > 0)
                return materiaalcodeQuery.First();
            return null;
        }

        public List<Ontlening> GetOntleendeProductenByAanvraagId(int aanvraag_id)
        {
            var ontleningQuery = from item in entities.Ontlening
                                 where item.aanvraag_id.Equals(aanvraag_id)
                                 select item;
            return ontleningQuery.ToList();
        }

        public ToebehorenType GetToebehorenTypeByToebehorenTypeId(int toebehorenType_id)
        {
            var toebehorenQuery = from producttype in entities.ToebehorenType
                                  where producttype.toebehorenType_id.Equals(toebehorenType_id)
                                  select producttype;
            if (toebehorenQuery.Count() > 0)
                return toebehorenQuery.First();
            return null;
        }

        public ToebehorenType GetTypeToebehorenByToebehorenScancode(String code)
        {
            var t = from product in entities.Toebehoren
                    where product.streepjescode.ToLower().Equals(code.ToLower())
                    select product.toebehorentype;
            if (t.Count() > 0)
                return t.First();
            return null;
        }

        public int GetAantalMateriaalDefect(int materiaalType_id)
        {
            return (from m in entities.Materiaal
                    where m.materiaalType_id == materiaalType_id && m.defect
                    select m).Count();
        }

        public int GetAantalMateriaalOntleenbaar(int materiaalType_id)
        {
            return (from m in entities.Materiaal
                    where m.materiaalType_id == materiaalType_id && m.ontleenbaar
                    select m).Count();
        }

        public int GetAantalMateriaal(int materiaalType_id)
        {
            return (from m in entities.Materiaal
                    where m.materiaalType_id == materiaalType_id
                    select m).Count();
        }

        public int GetAantalMateriaalOntleend(int MateriaalId, Aanvraag av)
        {
            return GetAantalMateriaalOntleend(MateriaalId, av.evenement.start, av.evenement.einde, av.aanvraag_id);
        }

        public int GetAantalMateriaalOntleend(int materiaalType_id, DateTime start, DateTime einde, int currentAanvraagId = 0)
        {
            var n = from m in entities.MateriaalBestelling
                    where m.materiaalType_id == materiaalType_id
                        && m.aanvraag.evenement.start < start
                        && m.aanvraag.evenement.einde > einde
                        && m.aanvraag_id != currentAanvraagId
                    select m.aantalGoedgekeurd;
            return (n.Count() > 0) ? n.Sum() : 0;
        }

        public void SetMaterialenForAanvraagId(List<MateriaalBestelling> LijstVanMateriaalBestellingen)
        {
            foreach (var mb in LijstVanMateriaalBestellingen)
            {
                if (mb.materiaalBestelling_id == 0)
                {
                    entities.MateriaalBestelling.AddObject(new MateriaalBestelling()
                    {
                        aantalAangevraagd = mb.aantalAangevraagd,
                        aantalGoedgekeurd = mb.aantalGoedgekeurd,
                        aanvraag_id = mb.aanvraag_id,
                        materiaalType_id = mb.materiaalType_id
                    });
                }
                else
                {
                    var MateriaalBestellingEntities = entities.MateriaalBestelling.Where(m => m.materiaalBestelling_id == mb.materiaalBestelling_id);
                    foreach (var m in MateriaalBestellingEntities)
                    {
                        m.materiaalType_id = mb.materiaalType_id;
                        m.aantalAangevraagd = mb.aantalAangevraagd;
                        m.aantalGoedgekeurd = mb.aantalGoedgekeurd;
                        m.aanvraag_id = mb.aanvraag_id;
                    }
                }
            }
            OpslaanWijzigingen();
        }

        public List<ToebehorenType> GetAllToebehorenTypes()
        {
            return (from t in entities.ToebehorenType select t).ToList();
        }

        public void AddMateriaal(Materiaal materiaal)
        {
            entities.AddToMateriaal(materiaal);
            OpslaanWijzigingen(false);
        }

        public void AddToebehoren(Toebehoren toebehoren)
        {
            entities.AddToToebehoren(toebehoren);
            OpslaanWijzigingen();
        }

        public bool StreepjescodeExists(string code)
        {
            int aantal = 0;
            code = code.ToLower();
            if (code.Length == 5)
            {
                if (code[0] == 'm')
                {
                    aantal = (from m in entities.Materiaal
                              where m.streepjescode.ToLower() == code
                              select m).Count();
                }
                if (code[0] == 't')
                {
                    aantal = (from m in entities.Toebehoren
                              where m.streepjescode.ToLower() == code
                              select m).Count();
                }
                if (code[0] == 'g')
                {
                    aantal = (from m in entities.Magazijnier
                              where m.streepjescode.ToLower() == code
                              select m).Count();
                }
            }
            return (aantal > 0);
        }

        public Materiaal GetMateriaalByScancode(string c)
        {
            var mq = from m in entities.Materiaal
                     where m.streepjescode == c
                     select m;
            if (mq.Count() > 0) return mq.First();
            else return null;
        }
        public Toebehoren GetToebehorenByScancode(string c)
        {
            var mq = from m in entities.Toebehoren
                     where m.streepjescode == c
                     select m;
            if (mq.Count() > 0) return mq.First();
            else return null;
        }

        public void SwitchCode(Materiaal oldMateriaal, string c)
        {
            var ontl = from o in entities.Ontlening
                       where o.streepjescode.ToLower() == oldMateriaal.streepjescode.ToLower()
                       select o;
            foreach (var o in ontl) o.streepjescode = c;

            entities.DeleteObject(oldMateriaal);
            entities.AddToMateriaal(new Materiaal()
            {
                defect = oldMateriaal.defect,
                materiaalType_id = oldMateriaal.materiaalType_id,
                ontleenbaar = oldMateriaal.ontleenbaar,
                streepjescode = c
            });
            OpslaanWijzigingen(false);
        }
        public void SwitchCode(Toebehoren oldToebehoren, string c)
        {
            var ontl = from o in entities.Ontlening
                       where o.streepjescode.ToLower() == oldToebehoren.streepjescode.ToLower()
                       select o;
            foreach (var o in ontl) o.streepjescode = c;
            entities.DeleteObject(oldToebehoren);
            entities.AddToToebehoren(new Toebehoren()
            {
                defect = oldToebehoren.defect,
                toebehorenType_id = oldToebehoren.toebehorenType_id,
                streepjescode = c
            });
            OpslaanWijzigingen();
        }

        public List<ToebehorenType> GetToebehorenTypesByMateriaalTypeId(int materiaalType_id)
        {
            var ToebehorenMateriaal = (from t in entities.ToebehorenMateriaal
                                       where t.materiaalType_id == materiaalType_id
                                       select t).ToList();
            List<ToebehorenType> ToebehorenTypes = new List<ToebehorenType>();
            foreach (var t in ToebehorenMateriaal)
                for (int i = 0; i < t.aantal; i++) ToebehorenTypes.Add(t.toebehorentype);
            return ToebehorenTypes;
        }

        public void RemoveToebehorenTypeFromMateriaalType(Materiaaltype materiaaltype, ToebehorenType toebehorenType)
        {
            var tbms = materiaaltype.toebehorenmateriaal.Where((t) => t.toebehorenType_id == toebehorenType.toebehorenType_id);
            if (tbms.Count() > 0)
            {
                var tbm = tbms.First();
                tbm.aantal--;
                if (tbm.aantal < 1) entities.DeleteObject(tbm);
                OpslaanWijzigingen();
            }
        }

        public List<ToebehorenMateriaal> GetToebehorenMateriaal(Materiaaltype materiaal)
        {
            return (from toeb in entities.ToebehorenMateriaal
                    where toeb.materiaaltype.materiaalType_id == materiaal.materiaalType_id
                    select toeb).ToList();
        }

        public void AddToebehorenMateriaal(ToebehorenMateriaal tm)
        {
            entities.AddToToebehorenMateriaal(tm);
        }

        public void RemoveToebehorenMateriaal(List<ToebehorenMateriaal> toebm)
        {
            foreach (ToebehorenMateriaal tm in toebm) entities.DeleteObject(tm);
        }

        public void RemoveToebehorenMateriaal(ToebehorenMateriaal toebehorenMateriaal)
        {
            entities.DeleteObject(toebehorenMateriaal);
        }

        internal void AddToMateriaaltype(Materiaaltype toestel)
        {
            entities.AddToMateriaaltype(toestel);
        }

        internal void AddToToebehorenType(ToebehorenType toe)
        {
            entities.AddToToebehorenType(toe);
        }

        internal bool TryDeleteToebehoren(Toebehoren toe)
        {
            bool output = true;
            try
            {
                Toebehoren toebehoren = (from t in entities.Toebehoren
                                         where t.streepjescode == toe.streepjescode
                                         select t).First();
                entities.DeleteObject(toebehoren);
                this.OpslaanWijzigingen(false);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
                output = false;
            }
            return output;
        }

        internal bool TryDeleteMateriaal(Materiaal materiaal)
        {
            bool output = true;
            try
            {
                entities.DeleteObject(materiaal);
            }
            catch
            {
                output = false;
            }
            return output;
        }

        internal void cleanExcessMateriaal(Aanvraag aanvraag)
        {
            List<MateriaalBestelling> bestellingen = aanvraag.materiaalbestelling.ToList();
            foreach (MateriaalBestelling mb in bestellingen)
            {
                if (mb.aantalAangevraagd == 0 && mb.aantalGoedgekeurd == 0)
                {
                    entities.DeleteObject(mb);
                }
            }
            entities.SaveChanges();
        }

    }
}
